﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 构造方法01
{
    // 构造方法本质上就是一个构造器，是为了实现类的实例化，并赋初值（用来产生类的实例）
    // 构造方法是一种特殊的方法，它没有返回值，而且必须与类的名字一致，他只能在初始化的时候被调用
    // 构造方法可以不显式的写出来，如果我们创建的类里面一个构造方法都没有，系统会自动提供一个没有参数的构造方法，
    // 如果说我们自己写了其他的构造方法，那么系统不再提供无参的构造方法，以后我们想使用无参的构造方法，必须要自己写
    // 构造方法之间可以互相调用，为了减少代码冗余
    // 构造器可以重载（为什么需要那么多参数不同的构造方法？为了在不同的资源下都能创建该类的对象）

    class Program
    {
        static void Main(string[] args)
        {
            // 后面的括号其实指的就是构造方法，只要你想创建类或结构的实例，就必须调用他们的构造方法
            // 构造方法负责对类里面的字段进行初始化
            Man kity = new Man();
            //kity.Age = 15;
            kity.Name = "Kity";
            kity.Country = "China";
            Console.WriteLine(kity.Name + " " + kity.Age + " " + kity.Country);
            Console.WriteLine("--------------------------------------------------------------");
            Man HelloKity = new Man(16, "HelloKity", "China");
            Console.WriteLine(HelloKity.Name + " " + HelloKity.Age + " " + HelloKity.Country);
            //int[] a = new int[]{ 1, 2, 3, 4, 6 };

            Console.WriteLine("----------------");
            Man kityCat = new Man(12, "kityCat");
            Console.WriteLine(kityCat.Age);

            //Man man = new Man(12);
        }
    }

    class Man
    {
        /// <summary>
        /// 当属性是只读的时候，我们在创建对象（类的实例）的时候通过构造方法给该属性赋值
        /// </summary>
        public int Age { get; } //只读
        public string Name { get; set; }
        public string Country { get; set; }

        // 类里面自带一个无参的默认构造方法，当没有其他构造方法，我们创建类的实例时，会自动调用该默认的无参构造方法
        // 当有其他构造方法的时候，如果我们不主动写出无参的构造方法，那么就不能使用该无参构造方法

        public Man()
        {
            Console.WriteLine("无参构造方法");
        }
        public Man(string name)
        {
            this.Name = name;
            Console.WriteLine("一个参数Name的构造方法");
        }

        /// <summary>
        /// 当构造方法使用private修饰的时候，不能从类外部调用构造器（不能从外部实例化），只能从类内部调用实现对象的实例化
        /// </summary>
        /// <param name="age"></param>
        private Man(int age)
        {
            this.Age = 10;
            Console.WriteLine("一个参数Age的构造方法");
        }

        public Man(int ageName, string name) :this(ageName)
        {
            //this.Age = 11;
            this.Name = name;
            Console.WriteLine("两个参数的构造方法");
        }

        public Man(string name, int ageName) : this(ageName)
        {
            //this.Age = 11;
            this.Name = name;
            Console.WriteLine("两个参数的构造方法");
        }

        public Man(int age, string name, string country):this(age, name)
        {
            //this.Age = age;
            //this.Name = name;
            this.Country = country;
            Console.WriteLine("有三个参数的有参构造方法");
        }
    }
}
